#pragma once
#include <cstdio>
#include <time.h>
#include <iostream>
#include <cstdarg>
/*
    日志宏
*/

enum Level
{
    INFO,
    DEBUG,
    ERROR,
    FATAL
};

static bool OnScreen = true;

#define EnableToScreen() OnScreen = true
#define EnableToFile() OnScreen = false

pthread_mutex_t logMutex = PTHREAD_MUTEX_INITIALIZER;

std::string levelToString(int level)
{
    switch (level)
    {
    case INFO:
        return "INFO";
    case DEBUG:
        return "DEBUG";
    case ERROR:
        return "ERROR";
    case FATAL:
        return "FATAL";
    default:
        return "";
    }
}

void logMessage(int level, const char *file, int line, const char *format, ...)
{
    // 可以设置在屏幕或者文件中打印日志
    FILE *out = nullptr;
    if (OnScreen)
    {
        out = stdout;
    }
    else
    {
        out = fopen("./log.txt", "a");
    }

    // 获取时间信息
    time_t t = time(nullptr);
    struct tm *lt = localtime(&t);
    char timeBuffer[32];
    strftime(timeBuffer, sizeof(timeBuffer) - 1, "%H-%M-%S", lt);
    timeBuffer[sizeof(timeBuffer)] = 0;

    // 获取可变参数
    char formatBuffer[1024];
    va_list arg;
    va_start(arg, format);
    vsnprintf(formatBuffer, sizeof(formatBuffer) - 1, format, arg);
    va_end(arg);
    std::string message = std::string("[") + levelToString(level) + "]" + "[" + timeBuffer + "]" + "[" + file + "]" + "[" + std::to_string(line) + "] " + formatBuffer;

    // 加锁后输出 --防止输出混乱
    pthread_mutex_lock(&logMutex);
    fprintf(out, "%s", message.c_str());
    pthread_mutex_unlock(&logMutex);
}

#define LOG(Level, format, ...)                                       \
    do                                                                \
    {                                                                 \
        logMessage(Level, __FILE__, __LINE__, format, ##__VA_ARGS__); \
    } while (0)
